﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Kyoh.Lib.WinForms;

namespace Kyoh.App.Renamer
{
    partial class RenameQueueManager : Form
    {
        public RenameOptionCollection Batch { get; private set; }
        public RenameQueueManager(RenameOptionCollection batch)
        {
            InitializeComponent();
            Batch = batch;
            if (Batch != null)
            {
                queueDataGridView.RowCount = Batch.Count;
                queueDataGridView.Refresh();
            }
        }

        private void queueDataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            if (Batch != null && e != null && e.RowIndex >= 0 && e.RowIndex < Batch.Count && Batch[e.RowIndex] != null)
            {
                switch (e.ColumnIndex)
                {
                    case 0:
                        e.Value = Batch[e.RowIndex].Method;
                        break;
                    case 1:
                        e.Value = Batch[e.RowIndex].Pattern;
                        break;
                    case 2:
                        e.Value = Batch[e.RowIndex].Replacement;
                        break;
                    case 3:
                        e.Value = Batch[e.RowIndex].Style;
                        break;
                    case 4:
                        e.Value = Batch[e.RowIndex].Grouped;
                        break;
                    case 5:
                        e.Value = Batch[e.RowIndex].Start;
                        break;
                    case 6:
                        e.Value = Batch[e.RowIndex].Step;
                        break;
                }
            }
        }

        private void SaveBatch(object sender, EventArgs e)
        {
            if (saveFileDialogBatchFile.ShowDialog() == DialogResult.OK)
                using (var stream = new FileStream(saveFileDialogBatchFile.FileName, FileMode.Create))
                    RenameOptionCollection.Serialize(stream, Batch);
        }

        private void LoadBatch(object sender, EventArgs e)
        {
            string fileName;

            if (openFileDialogBatchFile.ShowDialog() == DialogResult.OK)
                fileName = openFileDialogBatchFile.FileName;
            else
                return;

            RenameOptionCollection batch;
            try
            {
                using (var reader = new FileStream(fileName, FileMode.Open))
                    batch = RenameOptionCollection.Deserialize(reader);
                Batch = batch;
            }
            catch (Exception exc)
            {
                MessageBox.Show("Failed to load a batch file from '" + fileName + "'. (Error: " + exc.Message, "Error: Load a batch", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            if (Batch != null)
                queueDataGridView.RowCount = Batch.Count;
        }

        private IEnumerable<int> Selection(ListSortDirection listSortDirection)
        {
            var selection =
                from DataGridViewRow row in queueDataGridView.SelectedRows
                orderby row.Index ascending
                select row.Index;
            return listSortDirection == ListSortDirection.Ascending
                ? selection.ToArray()
                : selection.Reverse().ToArray();
        }

        private void Shift(int i, int p)
        {
            var rename = Batch[i];
            Batch.RemoveAt(i);
            Batch.Insert(p, rename);
            queueDataGridView.Rows[p].Selected = true;
            queueDataGridView.Rows[i].Selected = false;
        }

        private void MoveToTop(object sender, EventArgs e)
        {
            int toIndex = 0;
            foreach (var fromIndex in Selection(ListSortDirection.Ascending))
                Shift(fromIndex, toIndex++);
            queueDataGridView.Refresh();
        }

        private void MoveUp(object sender, EventArgs e)
        {
            foreach (var i in Selection(ListSortDirection.Ascending))
                if (i > 0)
                    Shift(i, i - 1);
            queueDataGridView.Refresh();
        }

        private void MoveDown(object sender, EventArgs e)
        {
            foreach (var i in Selection(ListSortDirection.Descending))
                if (i < Batch.Count - 1)
                    Shift(i, i + 1);
            queueDataGridView.Refresh();
        }

        private void MoveToBottom(object sender, EventArgs e)
        {
            int toIndex = Batch.Count - 1;
            foreach (var fromIndex in Selection(ListSortDirection.Descending))
                Shift(fromIndex, toIndex--);
            queueDataGridView.Refresh();
        }

        private void CloseForm(object sender, EventArgs e)
        {
            Close();
        }

        private void removeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var queueText = new StringBuilder();

            foreach (var i in Selection(ListSortDirection.Ascending))
                queueText.AppendLine(Batch[i].ToString());
            if (MemorizedConfirmationDialog.Show(Properties.Settings.Default.PropertyValues["ConfirmRemovingAgain"], string.Format(Properties.TextResources.ConfirmationToRemoveQueue, queueText.ToString()), Application.ProductName, MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, owner: this) == DialogResult.OK)
            {
                foreach (var i in Selection(ListSortDirection.Descending))
                    Batch.RemoveAt(i);
                queueDataGridView.Refresh();
            }
        }

        private void clearToolStripButton_Click(object sender, EventArgs e)
        {
            if (MemorizedConfirmationDialog.Show(Properties.Settings.Default.PropertyValues["ConfirmClearingAgain"], Properties.TextResources.ConfirmationToClearBatch, Application.ProductName, MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation, owner: this) == DialogResult.OK)
            {
                Batch.Clear();
                queueDataGridView.Refresh();
            }
        }
    }
}